import datetime
import os
import subprocess
import sys
import time

import win32print
from reportlab.graphics.shapes import Image as DrawingImage, Drawing, Line
from reportlab.lib import colors
from reportlab.lib.pagesizes import A4, letter
from reportlab.lib.styles import getSampleStyleSheet
from reportlab.lib.units import inch
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
from reportlab.pdfgen.canvas import Canvas
from reportlab.platypus import SimpleDocTemplate, Paragraph, Image, Spacer, Table

PAGE_HEIGHT = A4[1]
PAGE_WIDTH = A4[0]


class PdfCreate:

    def __init__(self):
        self.print_file_name = ''
        # 注册字体(提前准备好字体文件, 如果同一个文件需要多种字体可以注册多个)
        pdfmetrics.registerFont(TTFont('SimSun', 'SimSun.ttf'))

    # 绘制标题
    def draw_title(self, title: str):
        # 获取所有样式表
        style = getSampleStyleSheet()
        # 拿到标题样式
        ct = style['Heading2']
        # 单独设置样式相关属性
        ct.fontName = 'SimSun'  # 字体名
        ct.fontSize = 18  # 字体大小
        ct.leading = 10  # 行间距
        ct.textColor = colors.black  # 字体颜色
        ct.alignment = 1  # 居中
        ct.spaceAfter = 3  # 居中
        ct.bold = True
        # 创建标题对应的段落，并且返回
        return Paragraph(title, ct)

    # 绘制标题
    def draw_sub_title(self, title: str):
        # 获取所有样式表
        style = getSampleStyleSheet()
        # 拿到标题样式
        ct = style['Heading2']
        # 单独设置样式相关属性
        ct.fontName = 'SimSun'  # 字体名
        ct.fontSize = 12  # 字体大小
        ct.leading = 30  # 行间距
        ct.textColor = colors.black  # 字体颜色
        ct.alignment = 1  # 居中
        ct.spaceAfter = 3  # 居中
        ct.bold = True
        # 创建标题对应的段落，并且返回
        return Paragraph(title, ct)

    # 绘制小标题
    def draw_little_title(self, title: str):
        # 获取所有样式表
        style = getSampleStyleSheet()
        # 拿到标题样式
        ct = style['Normal']
        # 单独设置样式相关属性
        ct.fontName = 'SimSun'  # 字体名
        ct.fontSize = 14  # 字体大小
        ct.leading = 30  # 行间距
        ct.textColor = colors.black  # 字体颜色
        # 创建标题对应的段落，并且返回
        return Paragraph(title, ct)

    # 绘制普通段落内容
    def draw_text(self, text: str):
        # 获取所有样式表
        style = getSampleStyleSheet()
        # 获取普通样式
        ct = style['Normal']
        ct.fontName = 'SimSun'
        ct.fontSize = 12
        ct.wordWrap = 'CJK'  # 设置自动换行
        ct.alignment = 0  # 左对齐
        ct.firstLineIndent = 32  # 第一行开头空格
        ct.leading = 25
        return Paragraph(text, ct)

    # 绘制居中一行
    def draw_center_text(self, text: str):
        # 获取所有样式表
        style = getSampleStyleSheet()
        # 获取普通样式
        ct = style['Heading1']
        ct.fontName = 'SimSun'
        ct.fontSize = 12
        ct.wordWrap = 'CJK'  # 设置自动换行
        ct.alignment = 0  # 居中
        return Paragraph(text, ct)

    # 绘制图片
    def draw_img(self, path):
        img = Image(path)  # 读取指定路径下的图片
        img.drawWidth = 100  # 设置图片的宽度
        img.drawHeight = 100  # 设置图片的高度
        return img

    # 图片列表
    def draw_img_list(self, paths=list()):
        path_len = len(paths)
        d_list = []
        img_w = 80
        img_h = 80
        g_index = 5
        g_len = int(path_len / g_index) + (0 if path_len % g_index == 0 else 1)
        for i in range(g_len):
            if path_len <= g_index:
                d = Drawing(height=img_w)
                for j in range(path_len):
                    d.add(DrawingImage(j * (img_w + 10), 0, img_w, img_h, paths[j]))
                d_list.append(d)
            else:
                d = Drawing(height=img_w)
                for g in range(g_index):
                    if i * g_index + g < path_len:
                        d.add(DrawingImage(g * (img_w + 10), 0, img_w, img_h, paths[i * g_index + g]))
                d_list.append(d)
        return d_list

    def first_page(self, c: Canvas, doc):
        c.saveState()
        # 绘制页脚
        self.draw_page_info(c)
        c.restoreState()

    # 绘制页脚
    def draw_page_info(self, c: Canvas, date=datetime.date.today()):
        # 设置边框颜色
        c.setStrokeColor(colors.black)
        # 绘制线条
        c.line(30, PAGE_HEIGHT - 790, 570, PAGE_HEIGHT - 790)
        # 绘制页脚文字
        c.setFont("SimSun", 10)
        c.setFillColor(colors.black)
        c.drawImage(image="gw_logo.jpg", x=100, y=PAGE_HEIGHT - 165, width=45, height=40)
        # c.drawString(30, PAGE_HEIGHT - 810, "本报告不作为最终诊断结果，请前往医院复查")
        c.drawString(30, PAGE_HEIGHT - 810, "本报告不作为最终诊断结果，请咨询山东省公共卫生临床中心耳鼻咽喉科（83347700 83347235）")
        c.drawString(PAGE_WIDTH - 120, PAGE_HEIGHT - 810, f"生成日期：{date}")

    # 绘制表格
    def draw_table(self, *args):
        # 列宽度
        col_width = 120
        style = [
            ('FONTNAME', (0, 0), (-1, -1), 'SimSun'),  # 字体
            ('FONTSIZE', (0, 0), (-1, 0), 12),  # 第一行的字体大小
            ('FONTSIZE', (0, 1), (-1, -1), 10),  # 第二行到最后一行的字体大小
            ('BACKGROUND', (0, 0), (-1, 0), '#d5dae6'),  # 设置第一行背景颜色
            ('ALIGN', (0, 0), (-1, -1), 'CENTER'),  # 第一行水平居中
            ('ALIGN', (0, 1), (-1, -1), 'LEFT'),  # 第二行到最后一行左右左对齐
            ('ALIGN', (2, 1), (-1, -1), 'CENTER'),  # 第二行到最后一行左右左对齐
            ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),  # 所有表格上下居中对齐
            ('TEXTCOLOR', (0, 0), (-1, -1), colors.darkslategray),  # 设置表格内文字颜色
            ('GRID', (0, 0), (-1, -1), 0.5, colors.grey),  # 设置表格框线为grey色，线宽为0.5
            # ('SPAN', (0, 1), (0, 2)),  # 合并第一列二三行
            # ('SPAN', (0, 3), (0, 4)),  # 合并第一列三四行
            # ('SPAN', (0, 5), (0, 6)),  # 合并第一列五六行
            # ('SPAN', (0, 7), (0, 8)),  # 合并第一列五六行
        ]
        table = Table(args, colWidths=col_width, style=style)
        return table

    # 绘制表格
    def draw_table_info(self, *args):
        # 列宽度
        col_width = 120
        style = [
            ('FONTNAME', (0, 0), (-1, -1), 'SimSun'),
            ('FONTSIZE', (0, 0), (-1, -1), 12),
            ('ALIGN', (0, 0), (-1, -1), 'LEFT'),
            ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),  # 所有表格上下居中对齐
            ('TEXTCOLOR', (0, 0), (-1, -1), colors.black),  # 设置表格内文字颜色
            ('GRID', (0, 0), (-1, -1), 0.5, colors.white),  # 设置表格框线为grey色，线宽为0.5
        ]
        table = Table(args, colWidths=col_width, style=style)
        return table

    # 生成pdf
    def save(self, username: str, sex: str, age: int, id: str, there_img=list(), any_img=list(), table_data=list(),
             probability: str = ""):
        content = list()
        self.print_file_name = f"{time.time()}.pdf"
        # 创建文档
        doc = SimpleDocTemplate(self.print_file_name, pagesize=letter)
        content.append(self.draw_title('儿 童 腺 样 体 肥 大 预 诊 系 统'))
        content.append(self.draw_sub_title('Children\'s Adenoid Hypertrophy Pre-diagnosis System'))
        d = Drawing(height=0.5)
        d.add(Line(-50, 0, 500, 0))
        content.append(d)
        content.append(Spacer(1, 0.1 * inch))
        user_info = [
            (f'姓名：{username}', f'性别：{sex}', "", ""),
            (f'年龄：{age}岁', f'身份证号：{id}', "", ""),
        ]
        content.append(self.draw_table_info(*user_info))
        content.append(Spacer(1, 0.1 * inch))
        content.append(d)
        content.append(Spacer(1, 0.1 * inch))
        content.append(self.draw_little_title('三方位图'))
        img_list = self.draw_img_list(there_img)
        content.extend(img_list)
        content.append(Spacer(1, 0.1 * inch))
        content.append(self.draw_little_title('分析图'))
        img_list2 = self.draw_img_list(any_img)
        content.extend(img_list2)
        content.append(Spacer(1, 0.1 * inch))
        content.append(self.draw_little_title('分析'))
        if len(table_data) == 9:
            data = [
                ('指标（index）', '英文（en）', '值（value）', '权重（weight）'),
                ('左眼宽高比', 'LEWHR'),
                ('右眼宽高比', 'REWHR'),
                ('双唇上下缘比', 'ULMR'),
                ('额面比', 'FR'),
                ('唇/鼻小柱', 'L/C'),
                ('颧骨平面/眼', 'ZP/E'),
                ('鼻横距/口横距', 'NW/MW'),
                ('眼横距/鼻横距', 'IOD/NW'),
                ('鼻梁高度/鼻尖高度', 'NBH/NTH')
            ]
            for i in range(len(table_data)):
                data[i + 1] = data[i + 1] + table_data[i]
            content.append(self.draw_table(*data))
        content.append(Spacer(1, 0.1 * inch))
        content.append(self.draw_little_title('风险值'))
        content.append(self.draw_text(f'腺样体肥大的风险值{probability}'))
        # 保存文档
        doc.build(content, onFirstPage=self.first_page)

    def print(self, printer_name=None):
        if sys.platform == 'win32':
            printer_plat = win32print.GetDefaultPrinter()
            args = ["PDFtoPrinter.exe",
                    f"{self.print_file_name}",
                    f"{printer_plat}",
                    ]
            subprocess.run(args, encoding="utf-8", shell=True)
        else:
            os.system(f"lpr -P {printer_name} {self.print_file_name}")


def test(name, sex, age, zheng_list, feature_list, value_weight_list, proba):
    pdf = PdfCreate()
    # pdf.save("左玉伟", " ", 0, " ",
    #          ["user_left.png", "user_main.png", "user_right.png"],
    #          ["0.png", "1.png", "2.png", "3.png", "4.png"],
    #          [("0.3", "20%"),
    #           ("0.2", "15%"),
    #           ("0.3", "5%"),
    #           ("0.5", "15%"),
    #           ("0.6", "5%"),
    #           ("1.2", "5%"),
    #           ("1.4", "13%"),
    #           ("1.3", "12%"),
    #           ("0.3", "5%")],
    #          "67%")
    pdf.save(name, sex, age, " ",
             zheng_list,
             feature_list,
             value_weight_list,
             proba)
    pdf.print()


if __name__ == '__main__':
    test()
